package repl

import (
	"bufio"
	"dolphin/evaluator"
	"dolphin/lexer"
	"dolphin/object"
	"dolphin/parser"
	"fmt"
	"io"
)

const dolphin = `
                                      __
                                    _.-~  )
                     _..--~~~~,'   ,-/     _
                  .-'. . . .'   ,-','    ,' )
                ,'. . . _   ,--~,-'__..-'  ,'
              ,'. . .  (@)' ---~~~~      ,'
             /. . . . '~~             ,-'
            /. . . . .             ,-'
           ; . . . .  - .        ,'
          : . . . .        _     /
         . . . . .       /-____-/
        . . . . .      /        /
       . . . . .     (_______(:
`
const PROMPT = ">>"

func Start(in io.Reader, out io.Writer) {
	print(dolphin)

	scanner := bufio.NewScanner(in)
	env := object.NewEnvironment()

	for {
		fmt.Fprintf(out, PROMPT)
		scanned := scanner.Scan()
		if !scanned {
			return
		}

		line := scanner.Text()
		l := lexer.New(line)
		p := parser.New(l)

		program := p.ParseProgram()
		if len(p.Errors()) != 0 {
			printParserErrors(out, p.Errors())
			continue
		}

		evaluated := evaluator.Eval(program, env)
		if evaluated != nil {
			io.WriteString(out, evaluated.Inspect())
			io.WriteString(out, "\n")
		}
	}
}

func printParserErrors(out io.Writer, errors []string) {
	for _, msg := range errors {
		io.WriteString(out, "\t"+msg+"\n")
	}
}
